﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace EIA.WCFService.ClientProxy
{
    public class ProxyBase
    {
        private static string _token_cookie_key = "eia_user_token";
        private static string _token_key = "UserToken";
        private static string _token_namespace = "http://tempuri.org";
        private static string _endpoint_config = "BasicHttpBinding_ILogicalService";
        private static bool _interupt_if_user_token_not_in_cookies = false;
        private static object s_lockObj = new object();

        /// <summary>
        /// 获取或设置存储user token的cookie键名
        /// </summary>
        public static string TOKEN_COOKIE_KEY
        {
            get { return _token_cookie_key; }
            set
            {
                lock(s_lockObj)
                {
                    _token_cookie_key = value;
                }
            }
        }
        /// <summary>
        /// user token传入服务的消息头名称
        /// </summary>
        public static string TOKEN_KEY
        {
            get { return _token_key; }
            set
            {
                lock (s_lockObj)
                {
                    _token_key = value;
                }
            }
        }
        /// <summary>
        /// user token传入服务的名称空间
        /// </summary>
        public static string TOKEN_NAMESPACE
        {
            get { return _token_namespace; }
            set
            {
                lock (s_lockObj)
                {
                    _token_namespace = value;
                }
            }
        }

        public static string EndPointConfigName
        {
            get { return _endpoint_config; }
            set { _endpoint_config = value; }
        }

        public static event EventHandler OnUserTokenNotInCookies = null;
        public static bool InteruptIfUserTokenNotInCookies
        {
            get { return _interupt_if_user_token_not_in_cookies; }
            set
            {
                lock (s_lockObj)
                {
                    _interupt_if_user_token_not_in_cookies = value;
                }
            }
        }

        protected OperationContextScope CreateOperationContextScope(IContextChannel contextChannel)
        {
            string user_token = EIA.SLClient.Utility.CookiesUtils.GetCookie(TOKEN_COOKIE_KEY);
            if (string.IsNullOrEmpty(user_token))
            {
                if (OnUserTokenNotInCookies != null)
                {
                    OnUserTokenNotInCookies(this, new EventArgs());
                }
                if (InteruptIfUserTokenNotInCookies) return null;
            }

            OperationContextScope scope = null;
            lock (s_lockObj)
            {
                scope = new OperationContextScope(contextChannel);
                if (OperationContext.Current.OutgoingMessageHeaders.FindHeader(TOKEN_KEY, TOKEN_NAMESPACE) < 0)
                {
                    MessageHeader header = MessageHeader.CreateHeader(TOKEN_KEY, TOKEN_NAMESPACE, user_token);
                    OperationContext.Current.OutgoingMessageHeaders.Add(header);
                }
            }
            return scope;
        }

        protected IClientChannel CallFuncByAddToken2Headder(string business, string func, string json_args, Action callback, Action<Exception> errorCallback = null, Action cancelCallback = null)
        {
            LogicalService.LogicalServiceClient client = new LogicalService.LogicalServiceClient();
            client.CallCompleted += (s, e) =>
            {
                if (e.Error != null)
                {
                    if (errorCallback != null)
                        errorCallback(e.Error);
                }
                else if (e.Cancelled)
                {
                    if (cancelCallback != null) cancelCallback();
                }
                else
                {
                    if (callback != null) callback();
                }
                //try
                //{
                //    client.CloseAsync();
                //}
                //catch { }
            };

            OperationContextScope scope = CreateOperationContextScope(client.InnerChannel);
            if (scope == null)
            {
                if (errorCallback != null) errorCallback(new Exception("未找到用户凭据"));
                return null;
            }
            using (scope)
            {
                client.CallAsync(business, func, json_args);
            }
            return client.InnerChannel;
        }

        protected IClientChannel CallFuncByAddToken2Headder<T>(string business, string func, string json_args, Action<T> callback, Action<Exception> errorCallback = null, Action cancelCallback = null)
        {
            LogicalService.LogicalServiceClient client = new LogicalService.LogicalServiceClient(); 
            client.CallCompleted += (s, e) =>
            {
                if (e.Error != null)
                {
                    if(errorCallback!=null)
                        errorCallback(e.Error);
                }
                else if (e.Cancelled)
                {
                    if (cancelCallback != null) cancelCallback();
                }
                else
                {
                    T key = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(e.Result);
                    if (callback != null) callback(key);
                }
                //try
                //{
                //    client.CloseAsync();
                //}
                //catch { }
            };
            OperationContextScope scope = CreateOperationContextScope(client.InnerChannel);
            if (scope == null)
            {
                if (errorCallback != null) errorCallback(new Exception("未找到用户凭据"));
                return null;
            }
            using (scope)
            {
                client.CallAsync(business, func, json_args);
            }
            return client.InnerChannel;
        }

        protected IClientChannel CallFuncByAddToken2Headder(string remoteAddress, string business, string func, string json_args, Action callback, Action<Exception> errorCallback = null, Action cancelCallback = null)
        {
            LogicalService.LogicalServiceClient client = new LogicalService.LogicalServiceClient(EndPointConfigName, remoteAddress);
            client.CallCompleted += (s, e) =>
            {
                if (e.Error != null)
                {
                    if (errorCallback != null)
                        errorCallback(e.Error);
                }
                else if (e.Cancelled)
                {
                    if (cancelCallback != null) cancelCallback();
                }
                else
                {
                    if (callback != null) callback();
                }
                //try
                //{
                //    client.CloseAsync();
                //}
                //catch { }
            };

            OperationContextScope scope = CreateOperationContextScope(client.InnerChannel);
            if (scope == null)
            {
                if (errorCallback != null) errorCallback(new Exception("未找到用户凭据"));
                return null;
            }
            using (scope)
            {
                client.CallAsync(business, func, json_args);
            }
            return client.InnerChannel;
        }

        protected IClientChannel CallFuncByAddToken2Headder<T>(string remoteAddress, string business, string func, string json_args, Action<T> callback, Action<Exception> errorCallback = null, Action cancelCallback = null)
        {
            LogicalService.LogicalServiceClient client = new LogicalService.LogicalServiceClient(EndPointConfigName, remoteAddress);
            client.CallCompleted += (s, e) =>
            {
                if (e.Error != null)
                {
                    if (errorCallback != null)
                        errorCallback(e.Error);
                }
                else if (e.Cancelled)
                {
                    if (cancelCallback != null) cancelCallback();
                }
                else
                {
                    T key = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(e.Result);
                    if (callback != null) callback(key);
                }
                //try
                //{
                //    client.CloseAsync();
                //}
                //catch { }
            };
            OperationContextScope scope = CreateOperationContextScope(client.InnerChannel);
            if (scope == null)
            {
                if (errorCallback != null) errorCallback(new Exception("未找到用户凭据"));
                return null;
            }
            using (scope)
            {
                client.CallAsync(business, func, json_args);
            }
            return client.InnerChannel;
        }

    }
}
